import React, {Component, Fragment} from 'react';
import {StyleSheet, Alert} from 'react-native';
import {
  Constants,
  Colors,
  View,
  Text,
  Button,
  Slider
} from 'react-native-ui-lib';
import {TestCase, TestSuite} from '@rnoh/testerino';

interface SliderScreenProps {
  componentId: string;
}

interface SliderScreenState {
  sliderValue: number;
  sliderInitValue: number;
  sliderValue1: number;
  sliderMinValue: number;
  sliderMaxValue: number;
  sliderMinValue2: number;
  sliderMaxValue2: number;
  sliderMinValue3: number;
  sliderMaxValue3: number;
  forceLTR: boolean;
  isSeekStart: boolean;
  isSeekEnd: boolean;
}

const INITIAL_VALUE = 20;
const RANGE_INITIAL_MIN = 0;
const RANGE_INITIAL_MAX = 100;

export default class SliderScreen extends Component<SliderScreenProps, SliderScreenState> {
  state = {
    sliderValue: INITIAL_VALUE,
    sliderInitValue: INITIAL_VALUE,
    sliderValue1: INITIAL_VALUE,
    sliderMinValue: RANGE_INITIAL_MIN,
    sliderMaxValue: RANGE_INITIAL_MAX,
    sliderMinValue2: 25,
    sliderMaxValue2: 80,
    sliderMinValue3: 25,
    sliderMaxValue3: 80,
    forceLTR: false,
    isSeekStart: false,
    isSeekEnd: true
  };

  slider = React.createRef();
  slider1 = React.createRef();

  resetSlider = () => {
    // @ts-expect-error
    this.slider1.current?.reset();
  };

  onSliderRangeChange = (values: {min: number; max: number}) => {
    const {min, max} = values;
    this.setState({sliderMinValue: min, sliderMaxValue: max});
  };

  onSliderRangeChange2 = (values: {min: number; max: number}) => {
    const {min, max} = values;
    this.setState({sliderMinValue2: min, sliderMaxValue2: max});
  };
  
  onSliderRangeChange3 = (values: {min: number; max: number}) => {
    const {min, max} = values;
    this.setState({sliderMinValue3: min, sliderMaxValue3: max});
  };

  onSliderValueChange = (value: number) => {
    this.setState({sliderValue: value});
  };

  onSliderValueChange2 = (value: number) => {
    this.setState({sliderInitValue: value});
  };

  onSliderValueChange1 = (value: number) => {
    this.setState({sliderValue1: value});
  };

  onSliderReset = () => {
    this.setState({sliderInitValue: INITIAL_VALUE});
  };

  onSeekStart = () => {
    this.setState({isSeekStart: true});
    this.setState({isSeekEnd: false});
  }

  onSeekEnd = () => {
    this.setState({isSeekEnd: true});
    this.setState({isSeekStart: false});
  }

  getReverseStyle = () => {
    return Constants.isRTL && this.state.forceLTR && styles.ltr;
  };

  renderDefaultSliderExample() {
    const {sliderValue, forceLTR} = this.state;

    return (
      <Fragment>
        <Text $textDefault text70BO>
          Default slider
        </Text>

        <View row centerV style={this.getReverseStyle()}>
          <Slider
            onValueChange={this.onSliderValueChange}
            value={INITIAL_VALUE}
            minimumValue={0}
            maximumValue={100}
            step={1}
            containerStyle={styles.sliderContainer}
            disableRTL={forceLTR}
            ref={this.slider}
          />
          <Text bodySmall $textNeutral style={styles.text} numberOfLines={1}>
            {sliderValue}
          </Text>
        </View>
      </Fragment>
    );
  }

  renderCallbackExample() {
    const {sliderInitValue, forceLTR, isSeekStart, isSeekEnd} = this.state;

    return (
      <Fragment>
        <Text bodySmall $textNeutral numberOfLines={1}>
          {`isSeekStart: ${isSeekStart}, isSeekEnd: ${isSeekEnd}`}
        </Text>
        <View row centerV style={this.getReverseStyle()}>
          <Slider
            onValueChange={this.onSliderValueChange2}
            value={INITIAL_VALUE}
            accessible={true}
            minimumValue={0}
            maximumValue={100}
            onSeekStart={this.onSeekStart}
            onSeekEnd={this.onSeekEnd}
            step={1}
            containerStyle={styles.sliderContainer}
            ref={this.slider1}
            onReset={this.onSliderReset}
          />
          <Text bodySmall $textNeutral style={styles.text} numberOfLines={1}>
            {sliderInitValue}
          </Text>
        </View>
        <Button
          onPress={this.resetSlider}>
          <Text white>ResetSlider</Text>
        </Button>
      </Fragment>
    );
  }

  renderNegativeSliderExample() {
    return (
      <Fragment>
        <Slider
          minimumValue={-100}
          maximumValue={100}
          value={-30}
          minimumTrackTintColor={'red'}
          maximumTrackTintColor={'blue'}
          thumbTintColor={'green'}
          containerStyle={styles.slider}
        />
      </Fragment>
    );
  }

  renderDisabledSliderExample() {
    return (
      <Fragment>
        <Text>
          disabled: true
        </Text>
        <Slider minimumValue={100} maximumValue={200} value={120} containerStyle={styles.slider} disabled/>

        <Text marginT-10>
          disabled: false
        </Text>
        <Slider minimumValue={100} maximumValue={200} value={120} containerStyle={styles.slider} disabled={false}/>
      </Fragment>
    );
  }

  renderDisableActiveStylingExample() {
    return (
      <Fragment>
        <Text>
          disableActiveStyling: true
        </Text>
        <Slider minimumValue={0} maximumValue={100} value={0} containerStyle={styles.slider} disableActiveStyling/>

        <Text marginT-10>
          disableActiveStyling: false
        </Text>
        <Slider minimumValue={0} maximumValue={100} value={0} containerStyle={styles.slider} disableActiveStyling={false}/>
      </Fragment>
    );
  }

  renderActiveThumbStyleExample() {
    return (
      <Fragment>
        <Slider
          minimumValue={0} 
          maximumValue={100} 
          value={0} 
          containerStyle={styles.slider}
          activeThumbStyle={{
              // 颜色变化
              backgroundColor: '#ff0000',
              width:40,
              height:40,
              borderRadius:4
            }}
         />
      </Fragment>
    );
  }

  renderContainerStyleExample() {
    return (
      <Fragment>
        <Slider
          minimumValue={0} 
          maximumValue={100} 
          value={0} 
          containerStyle={{backgroundColor: '#00ff00', borderRadius:4, width:200, height: 30}}
         />
      </Fragment>
    );
  }

  renderTrackThumbStyleExample() {
    return (
      <Fragment>
        <Slider
          minimumValue={0} 
          maximumValue={100} 
          value={0} 
          containerStyle={{backgroundColor: '#00ff00'}}
          trackStyle={{
            width: 200,
            height: 8, 
            borderRadius: 0
          }}
          thumbStyle={{
            width: 30,
            height: 30,
            borderRadius: 6,
          }}
         />
      </Fragment>
    );
  }

  renderStepExample() {
    const {sliderValue1} = this.state;
    return (
      <Fragment>
        <View row centerV style={this.getReverseStyle()}>
          <Slider
            onValueChange={this.onSliderValueChange1}
            value={INITIAL_VALUE}
            minimumValue={0}
            maximumValue={100}
            step={2}
            containerStyle={styles.sliderContainer}
          />
          <Text bodySmall $textNeutral style={styles.text} numberOfLines={1}>
            {sliderValue1}
          </Text>
        </View>
      </Fragment>
    );
  }

  renderUseRangeExample() {
    const {sliderValue1} = this.state;
    return (
      <Fragment>
        <Text>
          useRange: true
        </Text>
        <Slider
          value={INITIAL_VALUE}
          minimumValue={0}
          maximumValue={100}
          step={1}
          containerStyle={styles.sliderContainer}
          useRange={true}
        />
        <Text>
          useRange: false
        </Text>
        <Slider
          value={INITIAL_VALUE}
          minimumValue={0}
          maximumValue={100}
          containerStyle={styles.sliderContainer}
          useRange={false}
        />
      </Fragment>
    );
  }

  renderDisableRTLExample() {
    return (
      <Fragment>
        <Text>
          disableRTL: true
        </Text>
        <Slider minimumValue={0} maximumValue={100} value={30} containerStyle={styles.slider} disableRTL={true}/>

        <Text marginT-10>
          disableRTL: false
        </Text>
        <Slider minimumValue={0} maximumValue={100} value={30} containerStyle={styles.slider} disableRTL={false}/>
      </Fragment>
    );
  }

  renderRangeSliderWithValuesExample() {
    const {sliderMinValue2, sliderMaxValue2, sliderMinValue3, sliderMaxValue3, forceLTR} = this.state;

    return (
      <Fragment>
        <Text>useGap: true</Text>
        <View row spread style={this.getReverseStyle()}>
          <Text bodySmall $textNeutral>
            min. {sliderMinValue2}%
          </Text>
          <Text bodySmall $textNeutral>
            max. {sliderMaxValue2}%
          </Text>
        </View>
        <Slider
          useRange={true}
          useGap={true}
          onRangeChange={this.onSliderRangeChange2}
          value={INITIAL_VALUE}
          minimumValue={0}
          maximumValue={100}
          step={1}
          disableRTL={forceLTR}
          initialMinimumValue={25}
          initialMaximumValue={80}
        />
        <Text>useGap: false</Text>
        <View row spread style={this.getReverseStyle()}>
          <Text bodySmall $textNeutral>
            min. {sliderMinValue3}%
          </Text>
          <Text bodySmall $textNeutral>
            max. {sliderMaxValue3}%
          </Text>
        </View>
        <Slider
		      useRange={true}
          useGap={false}
          onRangeChange={this.onSliderRangeChange3}
          value={INITIAL_VALUE}
          minimumValue={0}
          maximumValue={100}
          step={1}
          disableRTL={forceLTR}
          initialMinimumValue={25}
          initialMaximumValue={80}
        />
      </Fragment>
    );
  }

  renderAccessibleExample() {
    return (
      <Fragment>
        <Text $textDefault text70BO>
          accessible: true
        </Text>
        <View row centerV style={this.getReverseStyle()}>
          <Slider
            onValueChange={this.onSliderValueChange}
            value={INITIAL_VALUE}
            minimumValue={0}
            maximumValue={100}
            step={1}
            containerStyle={styles.sliderContainer}
            accessible={true}
          />
        </View>
        <Text $textDefault text70BO marginT-15>
          accessible: false
        </Text>
        <View row centerV style={this.getReverseStyle()}>
          <Slider
            onValueChange={this.onSliderValueChange}
            value={INITIAL_VALUE}
            minimumValue={0}
            maximumValue={100}
            step={1}
            containerStyle={styles.sliderContainer}
            accessible={false}
          />
        </View>
      </Fragment>
    );
  }

  renderMigrateExample() {
    return (
      <Fragment>
        <Text $textDefault text70BO>
          migrate: true
        </Text>
        <View row centerV style={this.getReverseStyle()} marginT-40>
          <Slider
            onValueChange={this.onSliderValueChange}
            value={INITIAL_VALUE}
            minimumValue={0}
            maximumValue={100}
            step={1}
            containerStyle={styles.sliderContainer}
            migrate={true}
            thumbHitSlop={50}
          />
        </View>
        <Text $textDefault text70BO marginT-60>
          migrate: false
        </Text>
        <View row centerV style={this.getReverseStyle()}>
          <Slider
            onValueChange={this.onSliderValueChange}
            value={INITIAL_VALUE}
            minimumValue={0}
            maximumValue={100}
            step={1}
            containerStyle={styles.sliderContainer}
            migrate={false}
            thumbHitSlop={50}
          />
        </View>
      </Fragment>
    );
    
  }

  renderTrackExample() {
    return (
      <Fragment>
        <View row centerV style={this.getReverseStyle()}>
          <Slider
            testID='123'
            value={INITIAL_VALUE}
            accessible={true}
            minimumValue={0}
            maximumValue={100}
            step={1}
            containerStyle={styles.sliderContainer}
            thumbStyle={{borderColor:'green', borderRadius:4}}
            thumbTintColor='yellow'
            renderTrack={this.renderSimpleTrack}
          />
        </View>
        <Button
          onPress={()=>{
            Alert.alert("testID: 123")
          }}>
          <Text white>testID</Text>
        </Button>
      </Fragment>
    );
  }

  renderSimpleTrack = () => {
    return (
      <View style={styles.trackContainer}>
        <View style={[styles.track, { backgroundColor: '#ff00ff' }]} />
      </View>
    );
  }

  render() {
    return (
      <TestSuite name="Sliders">
        <TestCase itShould="设置value=20, onValueChange, minimumValue=0, maximumValue=100">
          <View padding-20>
          {this.renderDefaultSliderExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置onSeekStart, onSeekEnd, onReset">
          <View padding-20>
          {this.renderCallbackExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置minimumTrackTintColor:red, thumbTintColor: green, maximumTrackTintColor: blue">
          <View padding-20>
          {this.renderNegativeSliderExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置disabled">
          <View padding-20>
          {this.renderDisabledSliderExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置disableActiveStyling">
          <View padding-20>
          {this.renderDisableActiveStylingExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置disableRTL">
          <View padding-20>
          {this.renderDisableRTLExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置activeThumbStyle:{backgroundColor: '#ff0000',width:40,height:40,borderRadius:4}">
          <View padding-20>
          {this.renderActiveThumbStyleExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置containerStyle:{backgroundColor: '#00ff00',borderRadius:4, width:200, height: 30}">
          <View padding-20>
          {this.renderContainerStyleExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置trackStyle:{width: 200,height: 8,borderRadius: 0}, thumbStyle:{width: 30,height: 30,borderRadius: 6}">
          <View padding-20>
          {this.renderTrackThumbStyleExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置step:2">
          <View padding-20>
          {this.renderStepExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置useRange">
          <View padding-20>
          {this.renderUseRangeExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置useGap, initialMinimumValue: 25, initialMaximumValue: 80, onRangeChange">
          <View padding-20>
          {this.renderRangeSliderWithValuesExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置 accessible">
          <View padding-20>
          {this.renderAccessibleExample()}
          </View>
        </TestCase>
        <TestCase itShould="设置 migrate">
          <View padding-20>
          {this.renderMigrateExample()}
          </View>
        </TestCase>
        <TestCase itShould="renderTrack, testID">
          <View padding-20>
          {this.renderTrackExample()}
          </View>
        </TestCase>
      </TestSuite>
    );
  }
}

const styles = StyleSheet.create({
  ltr: {
    flexDirection: 'row-reverse'
  },
  image: {
    tintColor: Colors.$iconNeutral
  },
  text: {
    width: 40
  },
  slider: {
    marginVertical: 6
  },
  sliderContainer: {
    flex: 1, // NOTE: to place a slider in a row layout you must set flex in its 'containerStyle'!!!
    marginHorizontal: 8
  },
  track: {
    height: 2
  },
  thumb: {
    width: 26,
    height: 26,
    borderRadius: 13,
    borderColor: Colors.violet40,
    borderWidth: 1,
    shadowColor: Colors.white
  },
  activeThumb: {
    width: 40,
    height: 40,
    borderRadius: 20,
    borderColor: Colors.yellow30,
    borderWidth: 2
  },
  box: {
    width: 20,
    height: 20,
    borderRadius: 4,
    borderWidth: 1,
    borderColor: Colors.$outlineDefault
  },
  group: {
    backgroundColor: Colors.$backgroundNeutralMedium,
    padding: 10,
    borderRadius: 6
  },
  trackContainer: {
    flex: 1,
    justifyContent: 'center',
  }
});
